/**
*	@class Vector3
*
*	@brief This class implements a 3D SSE vector class.
*
*	@author William McVicar
*/

#pragma once

#ifndef __VECTOR4_SSE_H_INCLUDED__
#define __VECTOR4_SSE_H_INCLUDED__

#ifdef PROTEIN_USE_SIMD

#pragma warning( disable : 4324 )
#pragma warning( disable : 4201 )

// Library Includes

// Local Includes

// Types

// Constants

// Prototypes

namespace Protein
{
 
PROTEIN_ALIGN16 class Vector4_f32
{
	//Functions
public:

	Vector4_f32();
	Vector4_f32( f32 x, f32 y, f32 z );
	Vector4_f32( f32 val );
	Vector4_f32( const Vector4_f32& other );
	Vector4_f32( f128 in );
	~Vector4_f32();

  void                set( f32 x, f32 y, f32 z );
  void                set( f32 val );

	Vector4_f32			    operator+( const Vector4_f32& rhs ) const;
	Vector4_f32			    operator-( const Vector4_f32& rhs ) const;
	Vector4_f32			    operator*( f32 rhs ) const;
	Vector4_f32			    operator/( f32 rhs ) const;
	Vector4_f32			    operator-() const;

	Vector4_f32&		    operator+=( const Vector4_f32& rhs );
	Vector4_f32&		    operator-=( const Vector4_f32& rhs );
	Vector4_f32&		    operator*=( float rhs );
	Vector4_f32&		    operator/=( float rhs );

	bool			          operator==( const Vector4_f32& rhs ) const;
	bool			          operator!=( const Vector4_f32& rhs ) const;
	bool			          operator> ( const Vector4_f32& rhs ) const;
	bool			          operator< ( const Vector4_f32& rhs ) const;
	bool			          operator>=( const Vector4_f32& rhs ) const;
	bool			          operator<=( const Vector4_f32& rhs ) const;

	f32			            dot( const Vector4_f32& in ) const;
	Vector4_f32		      cross( const Vector4_f32& in ) const;
  Vector4_f32         unitCross( const Vector4_f32& in ) const;
	f32			            length() const;
	f32			            lengthSqr() const;

	void			          normalise();
	Vector4_f32			    normalised() const;

	f32			            distance( const Vector4_f32& in );
	f32			            distanceSqr( const Vector4_f32& in );

	static float	      dot( const Vector4_f32& a, const Vector4_f32& b );
	static Vector4_f32	cross( const Vector4_f32& a, const Vector4_f32& b );
  static Vector4_f32  unitCross( const Vector4_f32& a, const Vector4_f32& b );
	static float	      length( const Vector4_f32& in );
	static float	      lengthSqr( const Vector4_f32& in );
	static float	      distance( const Vector4_f32& a, const Vector4_f32& b );
	static float	      distanceSqr( const Vector4_f32& a, const Vector4_f32& b );

protected:

private:

	//Members
public:

	static Vector4_f32				i;
	static Vector4_f32				j;
	static Vector4_f32				k;
	static Vector4_f32				negi;
	static Vector4_f32				negj;
	static Vector4_f32				negk;
	static Vector4_f32				negOne;
	static Vector4_f32				One;
	static Vector4_f32				Zero;

	union
	{
		struct
    { 
      f32 x;
      f32 y;
      f32 z; 
    };

	  f128 m_components;
  };
};

Vector4_f32 operator*( f32 val, const Vector4_f32& in );

typedef Vector4_f32 Vector4f;

}

#pragma warning( default : 4201 )
#pragma warning( default : 4324 )

#endif // PROTEIN_USE_SIMD

#endif // __VECTOR4_SSE_H_INCLUDED__